package com.liu.my_blog_system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liu.my_blog_system.entity.TbUploadFile;
import com.liu.my_blog_system.entity.TbUser;
import com.liu.my_blog_system.mapper.TbUploadFileMapper;
import com.liu.my_blog_system.service.TbUploadFileService;
import com.liu.my_blog_system.service.TbUserService;
import com.liu.my_blog_system.utils.Result;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * (TbImage)表服务实现类
 *
 * @author liuchengjie
 * @since 2021-04-20 14:16:50
 */
@Service
@Transactional
public class TbUploadFileServiceImpl extends ServiceImpl<TbUploadFileMapper, TbUploadFile> implements TbUploadFileService {

    @Autowired
    private TbUserService userService;
    /**
     * 文件上传
     * @param file
     * @return
     */
    @Override
    public Result uploadFile(MultipartFile file) throws IOException {
        //获取原始文件名称
        String filename = file.getOriginalFilename();
        //获取文件后缀名
        String extension = "." + FilenameUtils.getExtension(filename);
        //获取新文件名称 命名：时间戳+uuid+后缀
        String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + UUID.randomUUID().toString().substring(0,4)+extension;
        //获取资源路径 classpath的项目路径+static/files
        String path = ResourceUtils.getURL("classpath:").getPath()+"static/files";
        //新建一个时间文件夹用来标示分类
        String dateDir = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        //全路径：存放资源的路径+时间文件夹
        String dataDir = path + dateDir;


        //判断文件夹是否存在，不存在就创建
        File dataFile = new File(dataDir);
        if (!dataFile.exists()) {
            dataFile.mkdirs();
        }
        //文件上传至指定路径
        file.transferTo(new File(dataFile,newFileName));

        /*文件信息保存到数据库*/
        TbUploadFile uploadFile = new TbUploadFile();
        //获取文件格式
        String fileType = file.getContentType();
        //获取文件大小
        Long size = file.getSize();
        //获取用户id
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpServletResponse response = requestAttributes.getResponse();
        Map map = userService.checkUserStatus(request, response);
        if (map != null) {
            TbUser userInfo = (TbUser) map.get("userInfo");
            uploadFile.setUserId(userInfo.getId());
        }

        uploadFile.setOldFileName(filename);
        uploadFile.setNewFileName(newFileName);
        uploadFile.setExtension(extension);
        uploadFile.setPath(dateDir);
        uploadFile.setGlobalPath(dataDir);
        uploadFile.setType(fileType);
        uploadFile.setSize(size.toString());

        int row = baseMapper.insert(uploadFile);
        if (row > 0) {
            //获取保存到数据库里的文件id
            QueryWrapper<TbUploadFile> fileQueryWrapper = new QueryWrapper<>();
            fileQueryWrapper.eq("new_file_name",newFileName);
            TbUploadFile one = baseMapper.selectOne(fileQueryWrapper);
            return Result.ok().data("fileId",one);
        }
        return Result.error().message("上传失败");
    }

    /**
     * 获取图片
     * @param imageId
     * @return
     */
    @Override
    public void viewImage(String imageId,String openStyle,HttpServletResponse response) throws IOException {

        TbUploadFile uploadFile = baseMapper.selectById(imageId);
        //获取全路径
        String globalPath = uploadFile.getGlobalPath();
        FileInputStream fileInputStream = null;
        ServletOutputStream outputStream = null;
        try {
            fileInputStream = new FileInputStream(new File(globalPath, uploadFile.getNewFileName()));
            //根据传过来的参数判断是下载还是在线打开
            if ("attachment".equals(openStyle)) {
                //更新下载次数
                uploadFile.setDownCounts(uploadFile.getDownCounts() + 1);
                baseMapper.updateById(uploadFile);
                //以附件形式下载  点击会提供对话框选择另存为：
                response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(uploadFile.getOldFileName(), "utf-8"));
            }
            //获取输出流
            outputStream = response.getOutputStream();
            //检测是否是图片
            boolean isImage = uploadFile.getType().startsWith("image");
            if (isImage) {
                response.setContentType(uploadFile.getType());
            }
            //利用io流工具类实现流文件的拷贝，（输出显示在浏览器上在线打开方式）
            IOUtils.copy(fileInputStream, outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fileInputStream != null) {
                fileInputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }

    /**
     * 分页查询文件记录
     * @param current
     * @param size
     * @return
     */
    @Override
    public Result findFileListPage(Long current, Long size) {
        Page<TbUploadFile> uploadFilePage = new Page<>(current,size);
        Page<TbUploadFile> filePage = baseMapper.selectPage(uploadFilePage, null);
        long total = filePage.getTotal();
        List<TbUploadFile> records = filePage.getRecords();
        return Result.ok().data("total",total).data("records",records);
    }
}
